package org.russianpost;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.io.FileUtils;
import org.russianpost.fclient.Error;
import org.russianpost.fclient.*;
import org.russianpost.fclient.postserver.AnswerByTicketRequest;
import org.russianpost.fclient.postserver.AnswerByTicketResponse;
import org.russianpost.fclient.postserver.TicketRequest;
import org.russianpost.fclient.postserver.TicketResponse;
import org.russianpost.operationhistory.AuthorizationFault;
import org.russianpost.operationhistory.OperationHistory12;
import org.russianpost.operationhistory.OperationHistory12_Service;
import org.russianpost.operationhistory.OperationHistoryFault;
import org.russianpost.operationhistory.data.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.datatype.XMLGregorianCalendar;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class RussianPostTrackingUtil {
    private final static Logger LOG = LoggerFactory.getLogger(RussianPostTrackingUtil.class);
    public static final String LOGIN = "sgLLRdWCsgJIUI";
    public static final String PASSWORD = "f5CK4z6TWZPr";

    public static void main(String[] args) {
        List<String> barcodeList = Lists.newArrayList();
        barcodeList.add("80105709808608");
//        barcodeList.add("80108411106031");
//        barcodeList.add("80102911491116");
//        barcodeList.add("80105111594656");
//        barcodeList.add("80102711737612");
//        barcodeList.add("80104011441190");
//        barcodeList.add("80102711736653");
//        barcodeList.add("80102711736653");
//        barcodeList.add("80100511211400");
//        barcodeList.add("80109111373488");
//        barcodeList.add("80101611742337");
//        barcodeList.add("80108411105218");
//        barcodeList.add("80106211180756");
//        barcodeList.add("80108411105348");
//        barcodeList.add("80107911413571");
//        barcodeList.add("80106211181470");
//        barcodeList.add("80104011441022");
//        barcodeList.add("80108411105232");
//        barcodeList.add("80107911413380");
//        barcodeList.add("80097811477271");
//        barcodeList.add("80105111595127");
//        barcodeList.add("80097811342401");
//        barcodeList.add("80104011441916");
//        barcodeList.add("80107911413472");
//        barcodeList.add("80104011441985");
//        barcodeList.add("80097811600839");
//        barcodeList.add("80107911413250");
//        barcodeList.add("80104011442494");
//        barcodeList.add("80108411105171");
//        barcodeList.add("80107911413144");
//        barcodeList.add("80108411106062");
//        barcodeList.add("80101611741644");
//        barcodeList.add("80112011888228");
//        barcodeList.add("80112011888228");
//        barcodeList.add("80102911491055");
//        barcodeList.add("80105111595134");
//        barcodeList.add("80102911491475");
//        barcodeList.add("80105111594571");
//        barcodeList.add("80105111594571");
//        barcodeList.add("80107911413588");
//        barcodeList.add("80105111594755");
//        barcodeList.add("80107911412796");
//        barcodeList.add("80102911491468");
//        barcodeList.add("80100511211301");
//        barcodeList.add("80097811601089");
//        barcodeList.add("80102711737902");
//        barcodeList.add("80100511210069");
//        barcodeList.add("80097811600976");
//        barcodeList.add("80102911491239");
//        barcodeList.add("80102911491260");
//        barcodeList.add("80101611741507");
//        barcodeList.add("80102911491109");
//        barcodeList.add("80104011441305");
//        barcodeList.add("80106211181500");
//        barcodeList.add("80106211181456");
//        barcodeList.add("80101611742405");
//        barcodeList.add("80097811601027");
//        barcodeList.add("80104011442005");
//        barcodeList.add("80105111594076");
//        barcodeList.add("80097811722463");
//        barcodeList.add("80104011441589");
//        barcodeList.add("80097811601256");
//        barcodeList.add("80105111594472");
//        barcodeList.add("80097811534684");
//        barcodeList.add("80102711737865");
//        barcodeList.add("80099211447489");
//        barcodeList.add("80105111595431");
//        barcodeList.add("80106211181388");
//        barcodeList.add("80099211447663");
//        barcodeList.add("80109111373020");
//        barcodeList.add("80104011442166");
//        barcodeList.add("80105111594830");
//        barcodeList.add("80105111594670");
//        barcodeList.add("80109111372580");
//        barcodeList.add("80102911491000");
//        barcodeList.add("80106211180039");
//        barcodeList.add("80102911491826");
//        barcodeList.add("80108411105881");
//        barcodeList.add("80097811600204");
//        barcodeList.add("80102911491659");
//        barcodeList.add("80100511211066");
//        barcodeList.add("80105111594137");
//        barcodeList.add("80105111594748");
//        barcodeList.add("80104011441121");
//        barcodeList.add("80107911413946");
//        barcodeList.add("80108411106475");
//        barcodeList.add("80106211180305");
//        barcodeList.add("80108411105805");
//        barcodeList.add("80102911491864");
//        barcodeList.add("80101611741637");
//        barcodeList.add("80106211180954");
//        barcodeList.add("80109111373402");
//        barcodeList.add("80106211180473");
//        barcodeList.add("80107911413458");
//        barcodeList.add("80105111594847");
//        barcodeList.add("80108411105294");
//        barcodeList.add("80105111595158");
//        barcodeList.add("80107911413014");
//        barcodeList.add("80102711736608");
//        barcodeList.add("80104011441640");
//        barcodeList.add("80109111373303");
//        barcodeList.add("80112011888013");
//        barcodeList.add("80106211180657");
//        barcodeList.add("80097811600754");
//        barcodeList.add("80109111372054");
//        barcodeList.add("80099211448288");
//        barcodeList.add("80102911491451");
//        barcodeList.add("80097811600051");
//        barcodeList.add("80106211180404");
//        barcodeList.add("80108411106352");
//        barcodeList.add("80100511210588");
//        barcodeList.add("80105111595103");
//        barcodeList.add("80107911413137");
//        barcodeList.add("80107911413137");
//        barcodeList.add("80107911413137");
//        barcodeList.add("80107911413137");
//        barcodeList.add("80102911490799");
//        barcodeList.add("80104011441169");
//        barcodeList.add("80107911413434");
//        barcodeList.add("80108411106482");
//        barcodeList.add("80101611741446");
//        barcodeList.add("80097811477622");
//        barcodeList.add("80104011441466");
//        barcodeList.add("80102911491192");
//        barcodeList.add("80101611742474");
//        barcodeList.add("80097811477950");
//        barcodeList.add("80105111595011");
//        barcodeList.add("80097811534172");
//        barcodeList.add("80102911490867");
//        barcodeList.add("80107911413199");
//        barcodeList.add("80105111594113");
//        barcodeList.add("80107911413281");
//        barcodeList.add("80108411105126");
//        barcodeList.add("80106211180640");
//        barcodeList.add("80104011441084");
//        barcodeList.add("80106211180558");
//        barcodeList.add("80105111594854");
//        barcodeList.add("80107911413694");
//        barcodeList.add("80097811478421");
//        barcodeList.add("80107911413373");
//        barcodeList.add("80105111594502");
//        barcodeList.add("80105111594922");
//        barcodeList.add("80105111594335");
//        barcodeList.add("80108411105676");
//        barcodeList.add("80107911412857");
//        barcodeList.add("80097811477936");
//        barcodeList.add("80106211180992");
//        barcodeList.add("80101611742207");
//        barcodeList.add("80090011973529");
//        barcodeList.add("80108411105133");
//        barcodeList.add("80101611742221");
//        barcodeList.add("80106211181463");
//        barcodeList.add("80101611742214");
//        barcodeList.add("80099211448479");
//        barcodeList.add("80104011441824");
//        barcodeList.add("80105111594120");
//        barcodeList.add("80104011442432");
//        barcodeList.add("80105111595417");
//        barcodeList.add("80107911413595");
//        barcodeList.add("80085811751781");
//        barcodeList.add("80106211181265");
//        barcodeList.add("80102711736998");
//        barcodeList.add("80097811722784");
//        barcodeList.add("80090311304993");
//        barcodeList.add("80104011441183");
//        barcodeList.add("80097811535278");
//        barcodeList.add("80104011441336");
//        barcodeList.add("80109010466939");
//        barcodeList.add("80097811534257");
//        barcodeList.add("80104011442142");
//        barcodeList.add("80091411905660");
//        barcodeList.add("80097811342166");
//        barcodeList.add("80097811477240");
//        barcodeList.add("80102911491680");
//        barcodeList.add("80097811477684");
//        barcodeList.add("80102911491710");
//        barcodeList.add("80102711737124");
//        barcodeList.add("80099211447823");
//        barcodeList.add("80106211180879");
//        barcodeList.add("80105111595141");
//        barcodeList.add("80087711526384");
//        barcodeList.add("80101611742283");
//        barcodeList.add("80106211180510");
//        barcodeList.add("80090011974397");
//        barcodeList.add("80091411905875");
//        barcodeList.add("80097811600549");
//        barcodeList.add("80097811342036");
//        barcodeList.add("80102911491789");
//        barcodeList.add("80097811477196");
//        barcodeList.add("80102711736530");
//        barcodeList.add("80102711737872");
//        barcodeList.add("80083711296562");
//        barcodeList.add("80097811534905");
//        barcodeList.add("80097811478223");
//        barcodeList.add("80097811722111");
//        barcodeList.add("80097811600488");
//        barcodeList.add("80102911491482");
//        barcodeList.add("80097811342586");
//        barcodeList.add("80097811600945");
//        barcodeList.add("80083711295800");
//        barcodeList.add("80097811535391");
//        barcodeList.add("80099211448172");
//        barcodeList.add("80097811534073");
//        barcodeList.add("80080111068126");
//        barcodeList.add("80097811600679");
//        barcodeList.add("80097811722678");
//        barcodeList.add("80091411905516");
//        barcodeList.add("80100511210052");
//        barcodeList.add("80101611741682");
//        barcodeList.add("80083711296982");
//        barcodeList.add("80102911491703");
//        barcodeList.add("80097811535070");
        barcodeList.add("80097811721954");
        barcodeList.add("80097811721954");
        barcodeList.add("80106211180336");
        barcodeList.add("80099211447380");
        barcodeList.add("80102711736820");
        barcodeList.add("80100511210809");
        barcodeList.add("80097811600310");
        barcodeList.add("80099211448257");
        barcodeList.add("80100511210090");
        barcodeList.add("80102911491895");
        barcodeList.add("80101611741163");
        barcodeList.add("80090311305839");
        barcodeList.add("80097811342463");
        barcodeList.add("80099211448165");
        barcodeList.add("80101410140600");
        barcodeList.add("80097811721923");
        barcodeList.add("80105111594090");
        barcodeList.add("80107110620725");
        barcodeList.add("80080111068737");
        barcodeList.add("80099211447199");
        barcodeList.add("80105111595400");
        barcodeList.add("80105810209783");
        barcodeList.add("80097811601225");
        barcodeList.add("80097811534059");
        barcodeList.add("80101611742436");
        barcodeList.add("80085811752986");
        barcodeList.add("80099211448424");
        barcodeList.add("80101611742139");
        barcodeList.add("80097811535087");
        barcodeList.add("80091411905370");
        barcodeList.add("80097811478315");
        barcodeList.add("80100511211455");
        barcodeList.add("80104011441060");
        barcodeList.add("80102711737254");
        barcodeList.add("80104011442029");
        barcodeList.add("80102711737964");
        barcodeList.add("80104011441497");
        barcodeList.add("80097811342777");
        barcodeList.add("80099211448141");
        barcodeList.add("80106211180466");
        barcodeList.add("80097811600624");
        barcodeList.add("80097811342371");
        barcodeList.add("80097811722654");
        barcodeList.add("80100511211028");
        barcodeList.add("80102711737377");
        barcodeList.add("80106211180541");
        barcodeList.add("80091411905790");
        barcodeList.add("80097811722418");
        barcodeList.add("80097811601003");
        barcodeList.add("80099211448349");
        barcodeList.add("80097811477349");
        barcodeList.add("80097811477486");
        barcodeList.add("80099211447946");
        barcodeList.add("80101611741668");
        barcodeList.add("80107911412543");
        barcodeList.add("80097811600990");
        barcodeList.add("80080111067631");
        barcodeList.add("80090011973727");
        barcodeList.add("80091411905226");
        barcodeList.add("80102911491987");
        barcodeList.add("80106211180183");
        barcodeList.add("80102911491819");
        barcodeList.add("80097811722296");
        barcodeList.add("80097811601119");
        barcodeList.add("80100511210045");
        barcodeList.add("80102911490645");
        barcodeList.add("80104011441367");
        barcodeList.add("80100511210366");
        barcodeList.add("80094210606165");
        barcodeList.add("80097811535018");
        barcodeList.add("80097811343170");
        barcodeList.add("80097811343231");
        barcodeList.add("80097811600464");
        barcodeList.add("80080111068003");
        barcodeList.add("80102911491888");
        barcodeList.add("80097811342418");
        barcodeList.add("80091411905974");
        barcodeList.add("80102711737742");
        barcodeList.add("80097811601447");
        barcodeList.add("80100511210557");
        barcodeList.add("80090311305082");
        barcodeList.add("80097811477745");
        barcodeList.add("80104011442098");
        barcodeList.add("80102711737681");
        barcodeList.add("80085811752085");
        barcodeList.add("80104011441107");
        barcodeList.add("80106211180213");
        barcodeList.add("80105111594168");
        barcodeList.add("80100511210373");
        barcodeList.add("80097811342784");
        barcodeList.add("80097811343309");
        barcodeList.add("80097811343309");
        barcodeList.add("80107911413274");
        barcodeList.add("80107911413274");
        barcodeList.add("80101611741194");
        barcodeList.add("80105111594991");
        barcodeList.add("80100511211295");
        barcodeList.add("80105111594281");
        barcodeList.add("80091411905691");
        barcodeList.add("80090011974977");
        barcodeList.add("80102711736844");
        barcodeList.add("80102610392325");
        barcodeList.add("80085811752702");
        barcodeList.add("80104011441350");
        barcodeList.add("80102911491901");
        barcodeList.add("80099211447304");
        barcodeList.add("80100511210403");
        barcodeList.add("80091411905424");
        barcodeList.add("80101611742153");
        barcodeList.add("80099211447151");
        barcodeList.add("80100511210915");
        barcodeList.add("80097811342128");
        barcodeList.add("80090311305259");
        barcodeList.add("80100010274203");
        barcodeList.add("80100511210106");
        barcodeList.add("80100511211097");
        barcodeList.add("80091411905851");
        barcodeList.add("80097811721718");
        barcodeList.add("80101611741095");
        barcodeList.add("80090011974694");
        barcodeList.add("80099211448332");
        barcodeList.add("80102711737322");
        barcodeList.add("80097811534851");
        barcodeList.add("80091411904540");
        barcodeList.add("80085811751927");
        barcodeList.add("80106211180725");
        barcodeList.add("80102711736684");
        barcodeList.add("80090011974090");
        barcodeList.add("80105111594793");
        barcodeList.add("80102911491284");
        barcodeList.add("80087711525127");
        barcodeList.add("80104011441602");
        barcodeList.add("80097811722845");
        barcodeList.add("80111709508745");
        barcodeList.add("80091411904595");
        barcodeList.add("80097811722333");
        barcodeList.add("80102711737551");
        barcodeList.add("80100511211189");
        barcodeList.add("80097811722661");
        barcodeList.add("80097811601386");
        barcodeList.add("80105111594175");
        barcodeList.add("80097811478018");
        barcodeList.add("80091411905325");
        barcodeList.add("80090311304948");
        barcodeList.add("80101611741187");
        barcodeList.add("80102711737186");
        barcodeList.add("80102911491963");
        barcodeList.add("80097811477332");
        barcodeList.add("80090311304856");
        barcodeList.add("80080111067884");
        barcodeList.add("80100511210861");
        barcodeList.add("80097811534820");
        barcodeList.add("80102911490515");
        barcodeList.add("80100511211110");
        barcodeList.add("80102911490638");
        barcodeList.add("80097811343316");
        barcodeList.add("80090011973611");
        barcodeList.add("80091411905271");
        barcodeList.add("80097811534196");
        barcodeList.add("80102911491567");
        barcodeList.add("80097811477325");
        barcodeList.add("80090011974151");
        barcodeList.add("80097811342982");
        barcodeList.add("80090311304627");
        barcodeList.add("80099211448127");
        barcodeList.add("80097811342074");
        barcodeList.add("80097811601218");
        barcodeList.add("80099211447588");
        barcodeList.add("80102711736592");
        barcodeList.add("80101611742047");
        barcodeList.add("80097811342395");
        barcodeList.add("80101611742245");
        barcodeList.add("80097811534509");
        barcodeList.add("80091411905219");
        barcodeList.add("80109010466854");
        barcodeList.add("80101611742054");
        barcodeList.add("80087711525806");
        barcodeList.add("80097811477103");
        barcodeList.add("80091411905264");
        barcodeList.add("80101611742184");
        barcodeList.add("80101611742184");
        barcodeList.add("80091411904564");
        barcodeList.add("80097811477035");
        barcodeList.add("80099211447557");
        barcodeList.add("80097811477370");
        barcodeList.add("80105111594434");
        barcodeList.add("80097811535186");
        barcodeList.add("80102711737957");
        barcodeList.add("80102711737209");
        barcodeList.add("80109210014527");
        barcodeList.add("80107110619712");
        barcodeList.add("80099211447410");
        barcodeList.add("80102911491420");
        barcodeList.add("80102711737575");
        barcodeList.add("80102711737223");
        barcodeList.add("80102711737896");
        barcodeList.add("80099211447786");
        barcodeList.add("80099211447571");
        barcodeList.add("80097811722944");
        barcodeList.add("80097811342661");
        barcodeList.add("80097811343194");
        barcodeList.add("80097811600938");
        barcodeList.add("80099211448264");
        StringBuilder log = new StringBuilder();
        log.append("本次共运行" + barcodeList.size() + "条单号。\n");
        for (String barcode : barcodeList) {
            String s = doSingleTracking(barcode);
            String trackInfo = "查询物流轨迹信息，单号=" + barcode + "，轨迹信息=" + s + "。\n";
            log.append(trackInfo);
            LOG.info(trackInfo);
        }
        try {
            FileUtils.writeStringToFile(new java.io.File("D:/tracking_result.txt"), log.toString(), "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String doSingleTracking(String barcode) {
        AuthorizationHeader authorizationHeader = new AuthorizationHeader();
        authorizationHeader.setLogin(LOGIN);
        authorizationHeader.setPassword(PASSWORD);
//      authorizationHeader.setMustUnderstand("");

        OperationHistoryRequest operationHistoryRequest = new OperationHistoryRequest();
        operationHistoryRequest.setBarcode(barcode);
        operationHistoryRequest.setLanguage("ENG");
        operationHistoryRequest.setMessageType(0);

        OperationHistory12_Service service = new OperationHistory12_Service();
        OperationHistory12 port = service.getOperationHistory12Port();
        try {
            OperationHistoryData operationHistory = port.getOperationHistory(operationHistoryRequest, authorizationHeader);
            List<OperationHistoryRecord> historyRecordList = operationHistory.getHistoryRecord();
            for (OperationHistoryRecord record : historyRecordList) {
                OperationParameters operationParameters = record.getOperationParameters();
                Rtm02Parameter operType = operationParameters.getOperType();
                int operTypeId = operType.getId();
                String operTypeName = operType.getName();
                int operAttrId = 0;
                String operAttrName = null;
                Rtm02Parameter operAttr = operationParameters.getOperAttr();
                if (operAttr != null) {
                    operAttrId = operAttr.getId();
                    operAttrName = operAttr.getName();
                }
                XMLGregorianCalendar operDate = operationParameters.getOperDate();
                Date time = operDate.toGregorianCalendar().getTime();
                String eventTime = DateUtil.format(time, DatePattern.NORM_DATETIME_PATTERN);
                LOG.info("物流轨迹信息查询结果r={}", operTypeName + "-" + operAttrName + "-" + eventTime);
                StatusList status = new StatusList();

//                Map<String, Object> trackingInfo = status.getTrackingInfo(operTypeId, operAttrId);
//                LOG.info("物流轨迹信息查询结果r={}", JSON.toJSONString(trackingInfo));
            }
            return JSON.toJSONString(operationHistory);
        } catch (AuthorizationFault | OperationHistoryFault e) {
            return "查询失败，失败原因:" + e.getMessage();
        }
    }

    public static String doBathTracking(List<String> barcodeList) {
        ItemDataService itemDataService = new ItemDataService();
        FederalClient itemDataServicePort = itemDataService.getItemDataServicePort();


        /**
         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pos="http://fclient.russianpost.org/postserver" xmlns:fcl="http://fclient.russianpost.org">
         <soapenv:Header/>
         <soapenv:Body>
         <pos:ticketRequest>
         <request>
         <fcl:Item Barcode="RA123456788RU"/>
         <fcl:Item Barcode="RA123456789RU"/>
         <fcl:Item Barcode="RA123456780RU"/>
         ...
         </request>
         <login>my_login</login>
         <password>my_password</password>
         <language>RUS</language>
         </pos:ticketRequest>
         </soapenv:Body>
         </soapenv:Envelope>
         **/
        TicketRequest ticketRequest = new TicketRequest();
        ticketRequest.setLogin(LOGIN);
        ticketRequest.setPassword(PASSWORD);
        File f = new File();
        for (String barcode : barcodeList) {
            Item item = new Item();
            item.setBarcode("80105709808608");
            f.getItem().add(item);
        }
        ticketRequest.setRequest(f);
        TicketResponse ticket = itemDataServicePort.getTicket(ticketRequest);
        Error ticketError = ticket.getError();
        if (ticketError != null) {
            /**
             * ErrorTypeID - ErrorName
             * 2 - Data format of the query does not correspond to that one that is used in the protocol.
             * 3 - Failure of client authorization upon calling of the method.
             * 16 - Internal error of tracking service performance.
             * 18 - Concurrent request exceeded.
             * 20 - Unvalid language code.
             * 21 - The length of one or more of tracking numbers exceeds the maximum.
             * 22 - The lenght of file name exceeds the maximum.
             */
            String errorName = ticketError.getErrorName();
            BigInteger errorTypeID = ticketError.getErrorTypeID();
            System.out.println(JSON.toJSONString(ticketError));
            return "";
        }
        String ticketValue = ticket.getValue();
        System.out.println("获取到Ticket信息：" + ticketValue);

        AnswerByTicketRequest answerByTicketRequest = new AnswerByTicketRequest();
        answerByTicketRequest.setTicket(ticketValue);
        answerByTicketRequest.setLogin(LOGIN);
        answerByTicketRequest.setPassword(PASSWORD);
        AnswerByTicketResponse responseByTicket = itemDataServicePort.getResponseByTicket(answerByTicketRequest);
        Error responseByTicketError = responseByTicket.getError();
        if (responseByTicketError != null) {
            /**
             * ErrorTypeID - ErrorName
             * 2 - The format of query data does not correspond to that one that is used in the protocol.
             * 3 - Failure of client authorization failure upon calling of the method.
             * 6 - Response according to the ticket is not ready yet.
             * 12 - No information on the requested tracking number.
             * 16 - Internal error of tracking service performance.
             * 17 - Storage period of the response according to the ticket expired, the responce was deleted from the server.
             */
            String errorName = responseByTicketError.getErrorName();
            BigInteger errorTypeID = responseByTicketError.getErrorTypeID();
            System.out.println(JSON.toJSONString(responseByTicketError));
            return "";
        }
        File value = responseByTicket.getValue();
        for (Item item1 : value.getItem()) {
            String barcode = item1.getBarcode();
            for (Operation operation : item1.getOperation()) {
                // Local date and time of the operation. Example: "17.09.2015 17:20:48"
                String dateOper = operation.getDateOper();
                // Operation code
                BigInteger operTypeID = operation.getOperTypeID();
                // Attribute code
                BigInteger operCtgID = operation.getOperCtgID();
                // Operation name
                String operName = operation.getOperName();
                // Postcode of the place of the operation.
                String indexOper = operation.getIndexOper();
            }
        }

        return "";
    }
}